using System;
// ReSharper disable Unity.PerformanceCriticalCodeInvocation

namespace DanMuHelper.Logging
{
    using D = UnityEngine.Debug;

    public static partial class Echo
    {
        public enum EchoType
        {
            Info,
            Warning,
            Error,
            Exception
        }

        private static string GetMessage(EchoType echoType, object message, string callerFilePath, string callerMemberName)
        {
            switch (echoType)
            {
                case EchoType.Info:
                case EchoType.Warning:
                case EchoType.Error:
                    return $"[{echoType}] [{GetCallerTag(callerFilePath, callerMemberName)}] {message}";
                case EchoType.Exception:
                {
                    if (message is Exception excp)
                    {
                        return $"[{echoType}] [{GetCallerTag(callerFilePath, callerMemberName)}] {excp.GetType().FullName}: {excp.Message}";
                    }
                    return "";
                }
                default:
                    return "";
            }
        }

        internal static void Write(EchoType echoType, object message, string callerFilePath = "", string callerMemberName = "")
        {
            switch (echoType)
            {
                case EchoType.Info:
                {
                    D.Log(GetMessage(echoType, message, callerFilePath, callerMemberName));
                    break;
                }
                case EchoType.Warning:
                {
                    D.LogWarning(GetMessage(echoType, message, callerFilePath, callerMemberName));
                    break;
                }
                case EchoType.Error:
                {
                    D.LogError(GetMessage(echoType, message, callerFilePath, callerMemberName));
                    break;
                }
                case EchoType.Exception:
                {
                    if (message is Exception excp)
                    {
                        D.LogError(GetMessage(echoType, message, callerFilePath, callerMemberName));
                        D.LogException(excp);
                    }
                    break;
                }
            }
        }

        internal static void WriteInContext(EchoType echoType, UnityEngine.Object context, object message, string callerFilePath = "", string callerMemberName = "")
        {
            switch (echoType)
            {
                case EchoType.Info:
                {
                    D.Log(GetMessage(echoType, message, callerFilePath, callerMemberName), context);
                    break;
                }
                case EchoType.Warning:
                {
                    D.LogWarning(GetMessage(echoType, message, callerFilePath, callerMemberName), context);
                    break;
                }
                case EchoType.Error:
                {
                    D.LogError(GetMessage(echoType, message, callerFilePath, callerMemberName), context);
                    break;
                }
                case EchoType.Exception:
                {
                    if (message is Exception excp)
                    {
                        D.LogError(GetMessage(echoType, message, callerFilePath, callerMemberName), context);
                        D.LogException(excp, context);
                    }
                    break;
                }
            }
        }

        internal static void WriteRich(EchoType echoType, string color, object message, string callerFilePath = "", string callerMemberName = "")
        {
#if UNITY_EDITOR
            var content = $"<color={color}>{message}</color>";
            Write(echoType, content, callerFilePath, callerMemberName);
#else
            // 移动端不需要color, 否则日志里出现乱码
            Write(echoType, message, callerFilePath, callerMemberName);
#endif
        }

        internal static void WriteRichInContext(EchoType echoType, string color, UnityEngine.Object context, object message, string callerFilePath = "", string callerMemberName = "")
        {
#if UNITY_EDITOR
            var content = $"<color={color}>{message}</color>";
            WriteInContext(echoType, context, message, callerFilePath, callerMemberName);
#else
            WriteInContext(echoType, context, message, callerFilePath, callerMemberName);
#endif
        }

        private static string GetCallerTag(string callerFilePath, string callerMemberName)
        {
            if (string.IsNullOrEmpty(callerFilePath) && string.IsNullOrEmpty(callerMemberName))
                return null;
            var fileBaseName = "?";
            callerMemberName = string.IsNullOrEmpty(callerMemberName) ? "?" : callerMemberName;
            if (string.IsNullOrEmpty(callerFilePath)) return $"{fileBaseName}::{callerMemberName}";
            var pos = callerFilePath.LastIndexOfAny(Seperators);
            if (pos > 0)
            {
                var x = callerFilePath.Substring(pos + 1);
                if (x.Length > 3)
                {
                    x = x.Substring(0, x.Length - 3);
                }
                fileBaseName = x;
            }
            else
            {
                fileBaseName = callerFilePath;
            }
            return $"{fileBaseName}::{callerMemberName}";
        }

        static readonly char[] Seperators = new char[] { '/', '\\' };
    }
}